/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "ctc_asw_common.h"
#include "ctc_sync_ether.h"
#include "ctc_asw_sync_ether.h"
#include "ctc_asw_common.h"
#include "ctc_port.h"
#include "ctc_asw_chip.h"
#include "asw/include/drv_api.h"
/****************************************************************************
 *
* Defines and Macros
*
*****************************************************************************/
#define CTC_ASW_SYNC_ETHER_CLOCK_ID_NUM  2
#define CTC_ASW_SYNC_ETHER_DIVERD 10
/****************************************************************************
 *
* Global and Declaration
*
*********
********************************************************************/
/****************************************************************************
 *
* Function
*
*****************************************************************************/

/**
 @brief  Initialize SyncE module

 @param[in]  lchip Local chip ID

 @param[in]  sync_ether_global_cfg

 @return CTC_E_XXX

*/
int32
ctc_asw_sync_ether_init(uint8 lchip, void* sync_ether_global_cfg)
{
    return CTC_E_NONE;
}

int32
ctc_asw_sync_ether_deinit(uint8 lchip)
{
    return CTC_E_NONE;
}

/**
 @brief Set SyncE module config

 @param[in]  lchip Local chip ID

 @param[in]  synce_clock_id  <0-1>

 @param[in]  p_synce_cfg  Configuration of SyncE

 @return CTC_E_XXX

*/
int32
ctc_asw_sync_ether_set_cfg(uint8 lchip, uint8 sync_ether_clock_id, ctc_sync_ether_cfg_t* p_sync_ether_cfg)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint8 serdes_act_id = 0;
    uint32 value = 0;
    ds_t ds;

    CTC_PTR_VALID_CHECK(p_sync_ether_cfg);
    CTC_MAX_VALUE_CHECK(sync_ether_clock_id, CTC_ASW_SYNC_ETHER_CLOCK_ID_NUM-1);
    CTC_MAX_GPORT_CHECK(p_sync_ether_cfg->recovered_clock_lport);
    if ((p_sync_ether_cfg->divider != CTC_ASW_SYNC_ETHER_DIVERD) && (p_sync_ether_cfg->divider != 1))
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_API_LOCK(lchip);
    ret =  _ctc_asw_datapath_get_serdes_id(lchip, p_sync_ether_cfg->recovered_clock_lport, &serdes_act_id);
    value = (serdes_act_id > 8)? (serdes_act_id-8):(serdes_act_id+8);

    cmd = DRV_IOR(SyncECfg_t, DRV_ENTRY_FLAG);
    ret = ret?ret:DRV_IOCTL(lchip, 0, cmd, ds);
    SetSyncECfg(V, cfgOutEnA_f+sync_ether_clock_id, &ds, p_sync_ether_cfg->clock_output_en?1:0);
    SetSyncECfg(V, cfgSelFreqA_f+sync_ether_clock_id, &ds, (p_sync_ether_cfg->divider != 1)?0:1);
    SetSyncECfg(V, cfgSynceA_f+sync_ether_clock_id, &ds, value);
    cmd = DRV_IOW(SyncECfg_t, DRV_ENTRY_FLAG);
    ret = ret?ret: DRV_IOCTL(lchip, 0, cmd, ds);
   
    CTC_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief Get SyncE module config

 @param[in]  lchip Local chip ID

 @param[in]  synce_clock_id  <0-1>

 @param[out]  p_synce_cfg  Configuration of SyncE

 @return CTC_E_XXX

*/
int32
ctc_asw_sync_ether_get_cfg(uint8 lchip, uint8 sync_ether_clock_id, ctc_sync_ether_cfg_t* p_sync_ether_cfg)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    ds_t ds;
    uint32 value = 0;
    uint8 serdes_id = 0;
    uint32 gport = 0;

    CTC_PTR_VALID_CHECK(p_sync_ether_cfg);
    CTC_MAX_VALUE_CHECK(sync_ether_clock_id, CTC_ASW_SYNC_ETHER_CLOCK_ID_NUM-1);

    CTC_API_LOCK(lchip);
    /*read config*/
    cmd = DRV_IOR(SyncECfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, 0, cmd, &ds));

    p_sync_ether_cfg->clock_output_en = GetSyncECfg(V, cfgOutEnA_f+sync_ether_clock_id, &ds);
    p_sync_ether_cfg->divider = (0 != GetSyncECfg(V, cfgSelFreqA_f+sync_ether_clock_id, &ds))?1:CTC_ASW_SYNC_ETHER_DIVERD;
    value = GetSyncECfg(V, cfgSynceA_f+sync_ether_clock_id, &ds);
    serdes_id = (value >= 8)? (value-8):(value+8);
    ret = _ctc_asw_datapath_get_gport_id(lchip, serdes_id, &gport);
    p_sync_ether_cfg->recovered_clock_lport = gport;
    CTC_API_UNLOCK(lchip);
    return ret;
}
